/* eslint-disable @typescript-eslint/indent */
import { DataGridColumn, DataGridProps } from "../data-grid.props";
import { DataGridHeaderCell, HeaderCellStatus, UseDataView, UseSort } from "./types";

const booleanSorter = {
    'ascend': (preValue: boolean, postValue: boolean) => {
        return preValue === postValue ? 0 : ((preValue === false) ? -1 : 1);
    },
    'decend': (preValue: boolean, postValue: boolean) => {
        return preValue === postValue ? 0 : ((preValue === true) ? -1 : 1);
    }
};

const datetimeSorter = {
    'ascend': (preValue: string, postValue: string) => {
        const preDateValue = new Date(new Date(preValue).toLocaleDateString()).valueOf();
        const postDateValue = new Date(new Date(postValue).toLocaleDateString()).valueOf();
        return preDateValue === postDateValue ? 0 : ((preDateValue < postDateValue ? -1 : 1));
    },
    'decend': (preValue: string, postValue: string) => {
        const preDateValue = new Date(new Date(preValue).toLocaleDateString()).valueOf();
        const postDateValue = new Date(new Date(postValue).toLocaleDateString()).valueOf();
        return preDateValue === postDateValue ? 0 : ((preDateValue < postDateValue ? 1 : -1));
    }
};

const numericSorter = {
    'ascend': (preValue: number, postValue: number) => {
        return preValue === postValue ? 0 : (preValue < postValue ? -1 : 1);
    },
    'decend': (preValue: number, postValue: number) => {
        return preValue === postValue ? 0 : (preValue < postValue ? 1 : -1);
    }
};

const textSorter = {
    'ascend': (preValue: string, postValue: string) => {
        return preValue === postValue ? 0 : (preValue < postValue ? -1 : 1);
    },
    'decend': (preValue: string, postValue: string) => {
        return preValue === postValue ? 0 : (preValue < postValue ? 1 : -1);
    }
};

export function useSort(
    props: DataGridProps
): UseSort {
    const typeToSorterName = new Map<string, string>([
        ['boolean', 'boolean-sorter'],
        ['date', 'datetime-sorter'],
        ['datetime', 'datetime-sorter'],
        ['number', 'numeric-sorter'],
        ['string', 'text-sorter'],
        ['text', 'text-sorter'],
        ['enum', 'text-sorter'],
        ['reference', 'text-sorter']
    ]);

    const sorterMap = new Map<string, { 'ascend': any; 'decend': any }>([
        ['boolean-sorter', booleanSorter],
        ['datetime-sorter', datetimeSorter],
        ['numeric-sorter', numericSorter],
        ['text-sorter', textSorter]
    ]);

    function getSorterByColumn(column: DataGridColumn) {
        const fieldType = column?.dataType || 'string';
        const sorterName = typeToSorterName.get(fieldType) || 'text-sorter';
        const sorter = sorterMap.get(sorterName) || column?.sorter;
        return sorter;
    }

    function getSorter(headerCell: DataGridHeaderCell) {
        const sorter = getSorterByColumn(headerCell.column as DataGridColumn);
        return sorter;
    }

    function updateSorter(headerCell: DataGridHeaderCell, dataView: UseDataView) {
        const sorter = getSorter(headerCell) as any;
        const hasSorted = (headerCell.status & HeaderCellStatus.sortable) === HeaderCellStatus.sortable
            && (headerCell.status & HeaderCellStatus.sorted) === HeaderCellStatus.sorted;
        const ascending = (headerCell.status & HeaderCellStatus.ascending) === HeaderCellStatus.ascending;
        const decending = (headerCell.status & HeaderCellStatus.descending) === HeaderCellStatus.descending;
        if (hasSorted && sorter) {
            const sortMethod = ascending ? sorter.ascend : (decending ? sorter.decend : undefined);
            if (sortMethod) {
                dataView.addSorter(headerCell.field, { field: headerCell.field, compare: sortMethod });
            } else {
                dataView.removeSorter(headerCell.field);
            }
        } else {
            dataView.removeSorter(headerCell.field);
        }
    }

    return { getSorterByColumn, updateSorter };

}
